package com.invengo.module_check.ui.fragment.netmodel.utils;

import com.invengo.base.http.RobotBaseBean;
import com.invengo.library_db.entity.module_check.offline.UserBean;
import com.invengo.library_db.entity.module_robot.RobotTokenBean;

import java.util.concurrent.TimeUnit;

import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
import me.goldze.mvvmhabit.utils.cache.ACache;
import me.goldze.mvvmhabit.utils.cache.AKey;
import retrofit2.HttpException;

public  class RetryWithNewToken implements Function<Observable<Throwable>, ObservableSource<?>> {

        private int maxRetry;
        private int delay;
        private int retryCount = 0;

        public RetryWithNewToken(int maxRetry, int delay) {

        }

        private Observable<RobotBaseBean<UserBean>> tokenObservable;


        public RetryWithNewToken(Observable<RobotBaseBean<UserBean>> observable, int maxRetry, int delay) {
            this.tokenObservable = observable;
            this.maxRetry = maxRetry;
            this.delay = delay;
            retryCount = 0;
        }

        @Override
        public ObservableSource<?> apply(Observable<Throwable> throwableObservable) throws Exception {
            return throwableObservable.flatMap(throwable -> {
                if (throwable instanceof HttpException) {
                    if (((HttpException) throwable).code() == 401) {
                        if (++retryCount <= maxRetry) {
                            return tokenObservable.flatMap(robotTokenBeanRobotBaseBean -> {
                                if (robotTokenBeanRobotBaseBean.isSuccess() && robotTokenBeanRobotBaseBean.getResult() != null) {
//                                    ACache.getInstance().put(AKey.ROBOT_TOKEN, robotTokenBeanRobotBaseBean.getResult().getAccessToken());
                                    return Observable.timer(delay, TimeUnit.MILLISECONDS);
                                } else {
                                    return Observable.error(throwable);
                                }
                            }).subscribeOn(Schedulers.io());
                        } else {
                            return null;
                        }
                    } else {
                        return Observable.error(throwable);
                    }
                } else {
                    return Observable.error(throwable);
                }
            }).subscribeOn(Schedulers.io());
        }
    }
